﻿using SAP.Middleware.Connector;
using SDF.Plugin.Misc.SAPAdapter.Domain;
using SDF.Plugin.Misc.SAPAdapter.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using SDF.Core;

namespace SDF.Plugin.Misc.SAPAdapter.Extensions
{
    public static class Extends
    {
        /// <summary>
        /// SAPInstance对象转换为RfcDestination对象
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static RfcDestination ToRfcDestination(this SAPInstance instance)
        {
            RfcDestination rfcDest;
            var rfcPar = new RfcConfigParameters();

            //先添加必填参数
            rfcPar.Add(RfcConfigParameters.Name, instance.CodeName);
            rfcPar.Add(RfcConfigParameters.Client, instance.Client);
            rfcPar.Add(RfcConfigParameters.User, instance.User);
            rfcPar.Add(RfcConfigParameters.Password, instance.Password);
            rfcPar.Add(RfcConfigParameters.SystemNumber, instance.SystemNumber);
            rfcPar.Add(RfcConfigParameters.Language, instance.Language);
            if (!string.IsNullOrEmpty(instance.SystemID))
                rfcPar.Add(RfcConfigParameters.SystemID, instance.SystemID);
            if (!string.IsNullOrEmpty(instance.SAPRouter))
                rfcPar.Add(RfcConfigParameters.SAPRouter, instance.SAPRouter);

            //添加可选参数（普通登陆参数）
            if (!string.IsNullOrEmpty(instance.ApplicationServer))
                rfcPar.Add(RfcConfigParameters.AppServerHost, instance.ApplicationServer);

            //添加可选参数（服务器组参数）
            if (!string.IsNullOrEmpty(instance.MessageServerHost))
                rfcPar.Add(RfcConfigParameters.MessageServerHost, instance.MessageServerHost);

            if (!string.IsNullOrEmpty(instance.LogonGroup))
                rfcPar.Add(RfcConfigParameters.LogonGroup, instance.LogonGroup);

            //根据连接参数获取连接对象
            rfcDest = RfcDestinationManager.GetDestination(rfcPar);

            return rfcDest;
        }

        public static IEnumerable<TableInfoModel> ToTableInfoModel(this IRfcTable rfcTable)
        {
            List<TableInfoModel> result = new List<TableInfoModel>();

            DataTable loTable = new DataTable();

            foreach (IRfcStructure row in rfcTable)
            {
                TableInfoModel model = new TableInfoModel()
                {
                    FieldName = row.GetString("FIELDNAME"),
                    FieldDesc = row.GetString("REPTEXT").IsNullOrEmpty() ? row.GetString("SCRTEXT_S") : row.GetString("REPTEXT"),
                    FieldLength = row.GetInt("LENG"),
                    FieldDecimals = row.GetInt("DECIMALS"),
                    SortNo = row.GetInt("POSITION"),
                    FieldType = row.GetString("DATATYPE"),
                    FieldIntType = row.GetString("INTTYPE"),
                    IsPrimaryKey = row.GetString("KEYFLAG").Equals("X"),
                    DefaultValue = null
                };

                result.Add(model);
            }

            return result;
        }

        public static FunctionParamsModel ToFunctionParamsModel(this RfcParameterMetadata metaData)
        {
            if (metaData.DataType == RfcDataType.TABLE)
            {
                var result = new FunctionParamsModel()
                {
                    ParamName = metaData.Name,
                    ParamDesc = metaData.Documentation,
                    ParamType = metaData.DataType.ToString(),
                    Direction = metaData.Direction.ToString(),
                    DefaultValue = metaData.DefaultValue,
                    ChildParams = new List<FunctionParamsModel>()
                };

                var paramTable = metaData.ValueMetadataAsTableMetadata;
                for (int i = 0; i < paramTable.LineType.FieldCount; i++)
                {
                    RfcElementMetadata colMetadata = paramTable.LineType[i];
                    result.ChildParams.Add(colMetadata.ToFunctionParamsModel(metaData.Direction));
                }

                return result;
            }
            else if (metaData.DataType == RfcDataType.STRUCTURE)
            {
                var result = new FunctionParamsModel()
                {
                    ParamName = metaData.Name,
                    ParamDesc = metaData.Documentation,
                    ParamType = metaData.DataType.ToString(),
                    Direction = metaData.Direction.ToString(),
                    ChildParams = new List<FunctionParamsModel>()
                };

                var paramTable = metaData.ValueMetadataAsStructureMetadata;
                for (int i = 0; i < paramTable.FieldCount; i++)
                {
                    RfcElementMetadata colMetadata = paramTable[i];
                    result.ChildParams.Add(colMetadata.ToFunctionParamsModel(metaData.Direction));
                }

                return result;
            }
            else
            {
                return new FunctionParamsModel()
                {
                    ParamDecimals = metaData.Decimals,
                    ParamDesc = metaData.Documentation,
                    ParamLength = metaData.NucLength,
                    ParamName = metaData.Name,
                    ParamType = System.Text.RegularExpressions.Regex.Replace(metaData.DataType.ToString(), @"\d$", ""),//CHAR20 -->CHAR
                    Direction = metaData.Direction.ToString(),
                    DefaultValue = metaData.DefaultValue
                };
            }
        }

        public static FunctionParamsModel ToFunctionParamsModel(this RfcElementMetadata metaData, RfcDirection direction)
        {
            if (metaData.DataType == RfcDataType.TABLE)
            {
                var result = new FunctionParamsModel()
                {
                    ParamName = metaData.Name,
                    ParamDesc = metaData.Documentation,
                    ParamType = metaData.DataType.ToString(),
                    Direction = direction.ToString(),
                    ChildParams = new List<FunctionParamsModel>()
                };

                var paramTable = metaData.ValueMetadataAsTableMetadata;
                for (int i = 0; i < paramTable.LineType.FieldCount; i++)
                {
                    RfcElementMetadata colMetadata = paramTable.LineType[i];
                    result.ChildParams.Add(colMetadata.ToFunctionParamsModel(direction));
                }

                return result;
            }
            else if (metaData.DataType == RfcDataType.STRUCTURE)
            {
                var result = new FunctionParamsModel()
                {
                    ParamName = metaData.Name,
                    ParamDesc = metaData.Documentation,
                    ParamType = metaData.DataType.ToString(),
                    Direction = direction.ToString(),
                    ChildParams = new List<FunctionParamsModel>()
                };

                var paramTable = metaData.ValueMetadataAsStructureMetadata;
                for (int i = 0; i < paramTable.FieldCount; i++)
                {
                    RfcElementMetadata colMetadata = paramTable[i];
                    result.ChildParams.Add(colMetadata.ToFunctionParamsModel(direction));
                }

                return result;
            }
            else
            {
                return new FunctionParamsModel()
                {
                    ParamDecimals = metaData.Decimals,
                    ParamDesc = metaData.Documentation,
                    ParamLength = metaData.NucLength,
                    ParamName = metaData.Name,
                    ParamType = System.Text.RegularExpressions.Regex.Replace(metaData.DataType.ToString(), @"\d$", ""),//CHAR20 -->CHAR
                    Direction = direction.ToString()
                };
            }
        }
    }
}